package com.servlet.model.database;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import org.apache.commons.lang3.StringEscapeUtils;
import com.servlet.model.base.*;

/**
 * C'est la classe de la base de données.
 * Elle permet de chercher, modifier et supprimer des données de la base de données.
 */
public class Database {
	private String url;
	private String user;
	private String passwd;
	private Connection conn;
	
	/**
	 * Contructeur de Database
	 * @param url
	 * @param user
	 * @param passwd
	 */
	public Database(String url, String user, String passwd) {
		this.url = url;
		this.user = user;
		this.passwd = passwd;
	}

	/**
	 * 
	 * @return vrai réussi à connecter faux défaillance
	 */
	public boolean connect()
	{
		try {
			Class.forName("org.postgresql.Driver");
			System.out.println("DRIVER OK ! ");

			conn = DriverManager.getConnection(url, user, passwd);
			System.out.println("Connection effective !");

		} catch (Exception e) {
			System.out.println(e.getMessage());
			System.out.println("Conneter unsuccessfully");
			return false;
		}
		
		return true;
	}

	/**
	 * 
	 * @return vrai réussi à connecter faux défaillance
	 */
	public boolean deconnect() {
		try {
			if (conn != null)
				conn.close();
		} catch (SQLException e) {
			return false;
		}
		return true;
	}

	/**
	 * 
	 * @param selectSql
	 * @return resultSql : Column \t Column \n Column \t Column \n
	 */
	public String selectSQL(String selectSql) {
		String resultSql = "";

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			// On affiche le nom des colonnes
			// for (int i = 1; i <= resultMeta.getColumnCount(); i++)
			// System.out.print(resultMeta.getColumnName(i).toUpperCase() +
			// "\t");
			// System.out.println();

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null)
						resultSql += result.getObject(i).toString();

				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}
		return resultSql;
	}
	/**
	 * On autorise la mise à jour des données et la mise à jour de l'affichage
	 * @param updateSql
	 * @return true si pas de 
	 */
	public boolean updateSql(String updateSql) {
		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			System.out.println(" sql : " + updateSql );
			
			Statement state = conn.createStatement();
			state.executeUpdate(updateSql);
			// On récupère les MetaData
			state.close();

		} catch (Exception e) {
			return false;
		}
		return true;
	}

	/**
	 * Méthode qui permet d'inserer un sql qui ajoute des données
	 * @param insertSql
	 * @return
	 */
	public boolean insertSql(String insertSql) {
		return updateSql(insertSql);
	}

	/**
	 * Méthode qui permet d'inserer un sql qui supprime des données
	 * @param deleteSql
	 * @return
	 */
	public boolean deleteSql(String deleteSql) {
		return updateSql(deleteSql);
	}

	/**
	 * Méthode qui permet de retourner le area qui correspond à le hcode donné
	 * @param hcode
	 * @return
	 */
	public Area findArea(int hcode ) {
				
		String selectSql = "SELECT * FROM area WHERE hcode=" + hcode;

		Area area = new Area(Area.areaVide);

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return Area.areaVide;

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("city_code"))
							area.setCity_code(Integer.parseInt(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("country"))
							area.setCountry(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("city"))
							area.setCity(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return Area.areaVide;
		}
		return area;
	}
	
	/**
	 * Méthode qui permet de tester si le mot de passe donnée existe
	 * @param passwd
	 * @return true si oui, false si non
	 */
	public boolean existPasswd(String passwd)
	{
		//Protection contre les injections sql
		passwd = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(passwd));
				
		String selectSql = "SELECT * FROM Administrator WHERE passwd='" + passwd + "'";

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);

			if (result.wasNull())
				return true;
			
			int nb = 0;
			
			while (result.next())
			{
				nb++;
			}
			
			if ( nb == 0 )
				return false;

			result.close();
			state.close();

		} catch (Exception e)
		{
			return true;
		}

		return true;
	}
	
	public boolean existEmail(String email)
	{
		//Protection contre les injections sql
		email = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(email));
				
		String selectSql = "SELECT * FROM profile WHERE email='" + email + "'";

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);

			if (result.wasNull())
				return true;
			
			int nb = 0;
			
			while (result.next())
			{
				nb++;
			}
			
			if ( nb == 0 )
				return false;

			result.close();
			state.close();

		} catch (Exception e)
		{
			return true;
		}

		return true;
	}

	public Profile findProfile(String email) {
		
		//Protection contre les injections sql
		email = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(email));
		
		String selectSql = "SELECT * FROM profile WHERE email='" + email + "'";

		Profile profile = new Profile();
		profile.setEmail(email);

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("first_name"))
							profile.setFirst_name(StringEscapeUtils.unescapeEcmaScript(result.getObject(i)
									.toString()));
						if (resultMeta.getColumnName(i).equals("last_name"))
							profile.setLast_name(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("birth_date")) {
							Date date = Date.valueOf(result.getObject(i)
									.toString());
							profile.setBirth_date(date);
						}
						if (resultMeta.getColumnName(i)
								.equals("current_status")) {
							Status status = new Status(result.getObject(i)
									.toString());
							profile.setStatus(status);
						}
						if (resultMeta.getColumnName(i).equals("photo"))
							profile.setPhoto(result.getObject(i).toString());
						
						
						if (resultMeta.getColumnName(i).equals("world_area"))
						{
							int hcode = Integer.parseInt(result
									.getObject(i).toString());
							
							profile.setWorld_area( findArea(hcode) );
						}
						
						if (resultMeta.getColumnName(i).equals("nb_contacts_par_page"))
							profile.setNb_contacts_par_page(Integer.parseInt(result.getObject(i).toString()));
						
						if (resultMeta.getColumnName(i).equals("nb_news_par_page"))
							profile.setNb_news_par_page(Integer.parseInt(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("id"))
							profile.setId(Integer.parseInt(result.getObject(i).toString()));
						
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}
		profile.setIs_modified_birth_date(false);
		profile.setIs_modified_first_name(false);
		profile.setIs_modified_last_name(false);
		profile.setIs_modified_photo(false);
		profile.setIs_modified_status(false);
		profile.setIs_modified_world_area(false);

		return profile;
	}

	public ArrayList<String> findEmailByName(String name ) {
		String selectSql = "SELECT email FROM profile WHERE ";
		
		//Protection contre les injections sql
		name = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(name));
		
		if (name != null && name != "")
			selectSql += "upper(first_name) = upper('" + name + "')" + " OR upper(last_name) = upper('" + name + "')";
	
		ArrayList<String> list = new ArrayList<String>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			System.err.println("sql : "+selectSql);
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return list;

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("email")) {
							String email = StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString());
							if (!list.contains(email))
								list.add(email);
							break;
						}
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

		return list;
	}

	public ArrayList<String> findEmailByEnterprise(String enterprise) {
		
		//Protection contre les injections sql
		//enterprise = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(enterprise));
		
		String selectSql = "SELECT email FROM experience WHERE upper(enterprise)=upper('"
				+ enterprise + "')";

		ArrayList<String> list = new ArrayList<String>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			System.out.println("coucou " + result.toString());
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("email")) {
							String email = StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString());
							if (!list.contains(email))
								list.add(email);
							break;
						}
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}
		return list;
	}

	public ArrayList<String> findEmailBySchool(String school) {
		//Protection contre les injections sql
		//school = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(school));
		
		String selectSql = "SELECT email FROM study WHERE upper(school)=upper('" + school
				+ "')";

		ArrayList<String> list = new ArrayList<String>();

		System.out.println(selectSql);
		
		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("email")) {
							String email = StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString());
							if (!list.contains(email))
								list.add(email);
							break;
						}
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}

		return list;
	}

	public ArrayList<String> findEmailBySchoolTool(String email) {
		//Protection contre les injections sql
		email = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(email));
		
		String selectSql = "select study.email from (select * from study where email='"
				+ email
				+ "') t, study where t.email <> study.email and upper(t.school) = upper(study.school) and t.date_begin = study.date_begin and t.date_end= study.date_end";

		ArrayList<String> list = new ArrayList<String>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("email")) {
							String e = StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString());
							if (!list.contains(e))
								list.add(e);
							break;
						}
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}
		return list;
	}

	public ArrayList<String> findEmailByEntrepriseTool(String email) {
		
		//Protection contre les injections sql
		email = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(email));
		
		String selectSql = "select experience.email from (select * from experience where email='"
				+ email
				+ "') t, experience where t.email <> experience.email and upper(t.enterprise) = upper(experience.enterprise) and t.date_begin = experience.date_begin and t.date_end = experience.date_end";
		ArrayList<String> list = new ArrayList<String>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("email")) {
							String e = StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString());
							if (!list.contains(e))
								list.add(e);
							break;
						}
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}
		return list;
	}

	public ArrayList<Study> findStudies(String email) {
		//Protection contre les injections sql
		email = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(email));
		
		String selectSql = "SELECT * FROM study WHERE email='" + email + "'";

		ArrayList<Study> list = new ArrayList<Study>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				Study study = new Study();
				study.setEmail(email);

				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("school"))
							study.setSchool(StringEscapeUtils.unescapeEcmaScript(
									result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("date_begin")) {
							Date date_begin = Date.valueOf(result.getObject(i)
									.toString());
							study.setDateBegin(date_begin);
						}
						if (resultMeta.getColumnName(i).equals("date_end")) {
							Date date_end = Date.valueOf(result.getObject(i)
									.toString());
							study.setDateEnd(date_end);
						}
						if (resultMeta.getColumnName(i).equals("major"))
							study.setMajor(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("world_area")) {
							int hcode = Integer.parseInt(result
									.getObject(i).toString());
							study.setArea(findArea(hcode));
						}
					}
				}
				study.setIs_modified_area(false);
				study.setIs_modified_date_begin(false);
				study.setIs_modified_date_end(false);
				study.setIs_modified_major(false);
				study.setIs_modified_school(false);
				list.add(study);
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}

		return list;
	}

	public ArrayList<Experience> findExperiences(String email) {
		//Protection contre les injections sql
		email = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(email));
		
		String selectSql = "SELECT * FROM experience WHERE email='" + email
				+ "'";

		ArrayList<Experience> list = new ArrayList<Experience>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				Experience experience = new Experience();
				experience.setEmail(email);

				
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {						
						if (resultMeta.getColumnName(i).equals("enterprise"))
							experience.setEnterprise(StringEscapeUtils.unescapeEcmaScript(result.getObject(i)
									.toString()));
						if (resultMeta.getColumnName(i).equals("date_begin")) {
							Date date_begin = Date.valueOf(result.getObject(i)
									.toString());
							experience.setDateBegin(date_begin);
						}
						if (resultMeta.getColumnName(i).equals("date_end")) {
							Date date_end = Date.valueOf(result.getObject(i)
									.toString());
							experience.setDateEnd(date_end);
						}
						if (resultMeta.getColumnName(i).equals("post"))
							experience.setPost(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals(
								"activity_domain")) {
							Sector activity_domain = new Sector(result
									.getObject(i).toString() , false );
							experience.setActivityDomain(activity_domain);
						}
						if (resultMeta.getColumnName(i).equals("description"))
							experience.setDescription(StringEscapeUtils.unescapeEcmaScript(result.getObject(i)
									.toString()));
						if (resultMeta.getColumnName(i).equals("world_area")) {
							int hcode = Integer.parseInt(result
									.getObject(i).toString());
							experience.setArea(findArea(hcode));
						}
					}
				}
				experience.setIs_modified_activity_domain(false);
				experience.setIs_modified_area(false);
				experience.setIs_modified_date_begin(false);
				experience.setIs_modified_date_end(false);
				experience.setIs_modified_descriptionn(false);
				experience.setIs_modified_enterprise(false);
				experience.setIs_modified_post(false);
				list.add(experience);
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}

		return list;
	}

	public ArrayList<Contact> findContacts(String email) {
		//Protection contre les injections sql
		email = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(email));
		
		String selectSql = "SELECT * FROM contact WHERE email_user_1='" + email
				+ "' OR email_user_2='" + email + "'";

		ArrayList<Contact> list = new ArrayList<Contact>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				Contact contact = new Contact();

				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("email_user_1"))
							contact.setEmail_user1(StringEscapeUtils.unescapeEcmaScript(result.getObject(i)
									.toString()));
						if (resultMeta.getColumnName(i).equals("email_user_2"))
							contact.setEmail_user2(StringEscapeUtils.unescapeEcmaScript(result.getObject(i)
									.toString()));
						if (resultMeta.getColumnName(i).equals("is_accepted"))
						{
							boolean is_accepted = Boolean.parseBoolean(result.getObject(i).toString() );

							contact.setIs_accepted(is_accepted);
						}
						if (resultMeta.getColumnName(i).equals(
								"date_invitation")) {
							Date date_invitation = Date.valueOf(result
									.getObject(i).toString());
							contact.setDate_invitation(date_invitation);
						}
						if (resultMeta.getColumnName(i).equals(
								"date_acceptation")) {
							Date date_acceptation = Date.valueOf(result
									.getObject(i).toString());
							contact.setDate_acceptation(date_acceptation);
						}
					}
				}
				contact.setIs_modified_accepted(false);
				contact.setIs_modified_date_acceptation(false);
				contact.setIs_modified_date_invitation(false);
				list.add(contact);
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}

		return list;
	}

	public ArrayList<News> findNews(String email) {
		
		//Protection contre les injections sql
		email = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(email));
		
		String selectSql = "SELECT * FROM news WHERE email_user_2='" + email + "'";

		ArrayList<News> list = new ArrayList<News>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				News news = new News();

				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("email_user_1"))
							news.setEmail_user1(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("email_user_2"))
							news.setEmail_user2(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("date_publish")) {
							Date date_publish = Date.valueOf(result
									.getObject(i).toString());
							news.setDate_publish(date_publish);
						}
						if (resultMeta.getColumnName(i).equals("genre")) {
							int genre = Integer.parseInt(result
									.getObject(i).toString());
							news.setGenre(genre);
						}
						
						if (resultMeta.getColumnName(i).equals("id")) {
							int id = Integer.parseInt(result
									.getObject(i).toString());
							news.setId(id);
						}
						
						if (resultMeta.getColumnName(i).equals("info_sup"))
							news.setInfo_sup(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
					}
				}
				list.add(news);
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}

		return list;
	}
	
	public ArrayList<Study> findStudiesByMajor(String major)
	{
		//Protection contre les injections sql
		major = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(major));
		
		String selectSql = "SELECT * FROM study WHERE upper(major)=upper('" + major + "')";

		ArrayList<Study> list = new ArrayList<Study>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				Study study = new Study();

				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("email"))
							study.setEmail(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("school"))
							study.setSchool(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("date_begin")) {
							Date date_begin = Date.valueOf(result.getObject(i)
									.toString());
							study.setDateBegin(date_begin);
						}
						if (resultMeta.getColumnName(i).equals("date_end")) {
							Date date_end = Date.valueOf(result.getObject(i)
									.toString());
							study.setDateEnd(date_end);
						}
						if (resultMeta.getColumnName(i).equals("major"))
							study.setMajor(StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("world_area")) {
							int hcode = Integer.parseInt(result
									.getObject(i).toString());
							study.setArea(findArea(hcode));
						}
					}
				}
				study.setIs_modified_area(false);
				study.setIs_modified_date_begin(false);
				study.setIs_modified_date_end(false);
				study.setIs_modified_major(false);
				study.setIs_modified_school(false);
				list.add(study);
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}

		return list;
	}

	public Collection<String> findEveryEmail()
	{
		String selectSql = "SELECT email FROM profile ";

		System.out.println(selectSql);
		
		ArrayList<String> list = new ArrayList<String>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			if (result.wasNull())
				return null;

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("email")) {
							String email = StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString());
							if (!list.contains(email))
								list.add(email);
							break;
						}
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}

		return list;
	}
	
	public Administrator findAdmin()
	{
		//Protection contre les injections sql

		String selectSql = "SELECT * FROM administrator ";
		Administrator admin = new Administrator();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("coefprofile"))
						{
							admin.setCoefProfile(Double.parseDouble(result.getObject(i).toString()));
						}
						if (resultMeta.getColumnName(i).equals("coefpro"))
							admin.setCoefPro(Double.parseDouble(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("coefstudy"))
							admin.setCoefStudy(Double.parseDouble(result.getObject(i).toString()));
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}
		return admin;
	}
	
	public Administrator findAdmin(String passwd)
	{
		//Protection contre les injections sql
		passwd = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(passwd));
		
		String selectSql = "SELECT * FROM administrator WHERE passwd='" + passwd+"'";
		Administrator admin = new Administrator();
		admin.setPasswd(passwd);
		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();

			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("coefprofile"))
							admin.setCoefProfile(Double.parseDouble(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("coefpro"))
							admin.setCoefPro(Double.parseDouble(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("coefstudy"))
							admin.setCoefStudy(Double.parseDouble(result.getObject(i).toString()));
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}
		return admin;
	}

	public ArrayList<String> findEmailBySpecialite(String specialite)
	{
		//Protection contre les injections sql
		//specialite = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(specialite));
		
		String selectSql1 = "SELECT email FROM study WHERE upper(major)=upper('" + specialite + "')";
		String selectSql2 = "SELECT email FROM experience WHERE activity_domain='" + specialite + "'";
		
		//System.out.println(selectSql1);
		//System.out.println(selectSql2);
		ArrayList<String> list = new ArrayList<String>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result1 = state.executeQuery(selectSql1);
			// On récupère les MetaData
			ResultSetMetaData resultMeta1 = result1.getMetaData();
			
			while (result1.next()) {
				for (int i = 1; i <= resultMeta1.getColumnCount(); i++) {
					if (result1.getObject(i) != null) {
						if (resultMeta1.getColumnName(i).equals("email"))
						{
							String email = StringEscapeUtils.unescapeEcmaScript(result1.getObject(i).toString());
							if(!list.contains(email))
								list.add(email);
						}
					}
				}			
			}

			// L'objet ResultSet contient le résultat de la requête SQL
			result1 = state.executeQuery(selectSql2);
			// On récupère les MetaData
			resultMeta1 = result1.getMetaData();
			while (result1.next()) {
				for (int i = 1; i <= resultMeta1.getColumnCount(); i++) {
					if (result1.getObject(i) != null) {
						if (resultMeta1.getColumnName(i).equals("email"))
						{
							String email = StringEscapeUtils.unescapeEcmaScript(result1.getObject(i).toString());
							if(!list.contains(email))
								list.add(email);
						}
					}
				}			
			}
			result1.close();
			state.close();

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}

		return list;
	}
	
	public HashMap<String,String> getPasswdName(String email)
	{
		//Protection contre les injections sql
		email = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(email));
		
		String selectSql = "SELECT password,first_name,last_name FROM profile WHERE email='" + email+"'";

		HashMap<String,String> names = new HashMap<String,String>();

		try {
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();


			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals("password"))
							names.put("passwd", StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("first_name"))
							names.put("first_name", StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
						if (resultMeta.getColumnName(i).equals("last_name"))
							names.put("last_name", StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString()));
					}
				}
			}
			result.close();
			state.close();

		} catch (Exception e) {
			return null;
		}
		return names;
	}

	public ArrayList<String> getFieldOfTable(String table, String field, String word )
	{
		//Protection contre les injections sql
		table = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(table));
		word = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(word));
		field = StringEscapeUtils.escapeEcmaScript(StringEscapeUtils.escapeHtml4(field));
				
		String selectSql = "SELECT " + field + " FROM " + table + " WHERE " + field + " like '" + word +"%'";

		ArrayList<String> list = new ArrayList<String>();
		
		//System.out.println(selectSql);
	
		try
		{
			// On autorise la mise à jour des données et la mise à jour de
			// l'affichage
			Statement state = conn
					.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
							ResultSet.CONCUR_UPDATABLE);
			// L'objet ResultSet contient le résultat de la requête SQL
			ResultSet result = state.executeQuery(selectSql);
			// On récupère les MetaData
			ResultSetMetaData resultMeta = result.getMetaData();
	
			if (result.wasNull())
				return null;
	
			while (result.next()) {
				for (int i = 1; i <= resultMeta.getColumnCount(); i++) {
					if (result.getObject(i) != null) {
						if (resultMeta.getColumnName(i).equals(field)) {
							String email = StringEscapeUtils.unescapeEcmaScript(result.getObject(i).toString());
							if (!list.contains(email))
								list.add(email);
							break;
						}
					}
				}
			}
			result.close();
			state.close();
	
		} catch (Exception e) {
			return null;
		}
	
		return list;
	}
}
